package io.github.iogogogo.commons.util;

import com.google.common.base.CaseFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * Created by tao.zeng on 2024/11/7.
 */
public class SuperStringUtils extends StringUtils {

    private static final String[] EMPTY_STRING_ARRAY = new String[0];


    public static String[] tokenizeToStringArray(String str, String delimiters) {
        return tokenizeToStringArray(str, delimiters, true, true);
    }

    public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
        if (str == null) {
            return EMPTY_STRING_ARRAY;
        } else {
            StringTokenizer st = new StringTokenizer(str, delimiters);
            List<String> tokens = new ArrayList<>();

            while (true) {
                String token;
                do {
                    if (!st.hasMoreTokens()) {
                        return toStringArray(tokens);
                    }

                    token = st.nextToken();
                    if (trimTokens) {
                        token = token.trim();
                    }
                } while (ignoreEmptyTokens && token.length() <= 0);

                tokens.add(token);
            }
        }
    }


    public static String[] toStringArray(Collection<String> collection) {
        return !CollectionUtils.isEmpty(collection) ? collection.toArray(EMPTY_STRING_ARRAY) : EMPTY_STRING_ARRAY;
    }

    public static String[] toStringArray(Enumeration<String> enumeration) {
        return enumeration != null ? toStringArray(Collections.list(enumeration)) : EMPTY_STRING_ARRAY;
    }


    public static String[] delimitedListToStringArray(String str, String delimiter) {
        return delimitedListToStringArray(str, delimiter, null);
    }

    public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) {
        if (str == null) {
            return EMPTY_STRING_ARRAY;
        } else if (delimiter == null) {
            return new String[]{str};
        } else {
            List<String> result = new ArrayList<>();
            int pos;
            if (delimiter.isEmpty()) {
                for (pos = 0; pos < str.length(); ++pos) {
                    result.add(deleteAny(str.substring(pos, pos + 1), charsToDelete));
                }
            } else {
                int delPos;
                for (pos = 0; (delPos = str.indexOf(delimiter, pos)) != -1; pos = delPos + delimiter.length()) {
                    result.add(deleteAny(str.substring(pos, delPos), charsToDelete));
                }

                if (str.length() > 0 && pos <= str.length()) {
                    result.add(deleteAny(str.substring(pos), charsToDelete));
                }
            }

            return toStringArray(result);
        }
    }

    public static String deleteAny(String inString, String charsToDelete) {
        if (StringUtils.isNoneEmpty(inString, charsToDelete)) {
            int lastCharIndex = 0;
            char[] result = new char[inString.length()];

            for (int i = 0; i < inString.length(); ++i) {
                char c = inString.charAt(i);
                if (charsToDelete.indexOf(c) == -1) {
                    result[lastCharIndex++] = c;
                }
            }

            if (lastCharIndex == inString.length()) {
                return inString;
            } else {
                return new String(result, 0, lastCharIndex);
            }
        } else {
            return inString;
        }
    }

    /**
     * 驼峰转下划线
     *
     * @param text 待转换文本
     * @return 驼峰转下划线的文本
     */
    public static String humpToLine(String text) {
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, text);
    }

    /**
     * 下划线转驼峰
     *
     * @param text 待转换文本
     * @return 下划线转驼峰后的文本
     */
    public static String lineToHump(String text) {
        return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, text);
    }


    /**
     * 脱敏
     *
     * @param str          脱敏字符串
     * @param startInclude 开头保留几位
     * @param endExclude   结束保留几位
     * @return 脱敏结果
     */
    public static String sensitive(CharSequence str, int startInclude, int endExclude) {
        return replace(str, startInclude, endExclude, '*');
    }


    /**
     * 字符替换
     *
     * @param str          原始字符串
     * @param startInclude 开头保留几位
     * @param endExclude   结束保留几位
     * @param replacedChar 替换的字符
     * @return 替换结果
     */
    public static String replace(CharSequence str, int startInclude, int endExclude, char replacedChar) {
        String originalStr = String.valueOf(str);
        int[] strCodePoints = originalStr.codePoints().toArray();
        int strLength = strCodePoints.length;
        if (startInclude > strLength) {
            return originalStr;
        } else {
            if (endExclude > strLength) {
                endExclude = strLength;
            }

            if (startInclude > endExclude) {
                return originalStr;
            } else {
                StringBuilder stringBuilder = new StringBuilder();

                for (int i = 0; i < strLength; ++i) {
                    if (i >= startInclude && i < endExclude) {
                        stringBuilder.append(replacedChar);
                    } else {
                        stringBuilder.append(new String(strCodePoints, i, 1));
                    }
                }

                return stringBuilder.toString();
            }
        }
    }
}
